from flask_restful import Resource, reqparse
from flask import request
from models import db, BillCategory, BillSubCategory, Record, User
from utils import api_response
from datetime import datetime, date

class BillCategoryList(Resource):
    def get(self):
        """获取账单分类列表"""
        # 获取查询参数
        parser = reqparse.RequestParser()
        parser.add_argument('type', type=int, location='args')  # 0-支出, 1-收入
        args = parser.parse_args()
        
        # 查询条件
        query = BillCategory.query
        if args['type'] is not None:
            query = query.filter_by(type=args['type'])
        
        categories = query.order_by(BillCategory.sort_order, BillCategory.id).all()
        
        return api_response({
            'categories': [category.to_dict() for category in categories]
        })
    
    def post(self):
        """创建账单分类"""
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str, required=True, help='分类名称不能为空')
        parser.add_argument('icon', type=str)
        parser.add_argument('type', type=int, required=True, help='分类类型不能为空')
        parser.add_argument('sort_order', type=int, default=0)
        args = parser.parse_args()
        
        # 检查同名分类是否已存在
        existing_category = BillCategory.query.filter_by(name=args['name'], type=args['type']).first()
        if existing_category:
            return api_response({'message': '同名分类已存在'}, code=400)
        
        category = BillCategory(
            name=args['name'],
            icon=args['icon'],
            type=args['type'],
            sort_order=args['sort_order']
        )
        
        db.session.add(category)
        db.session.commit()
        
        return api_response(category.to_dict(), message='分类创建成功')

class BillCategoryDetail(Resource):
    def get(self, category_id):
        """获取账单分类详情"""
        category = BillCategory.query.get(category_id)
        if not category:
            return api_response({'message': '分类不存在'}, code=404)
        
        return api_response(category.to_dict())
    
    def put(self, category_id):
        """更新账单分类"""
        category = BillCategory.query.get(category_id)
        if not category:
            return api_response({'message': '分类不存在'}, code=404)
        
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str)
        parser.add_argument('icon', type=str)
        parser.add_argument('type', type=int)
        parser.add_argument('sort_order', type=int)
        args = parser.parse_args()
        
        # 如果名称和类型有修改，检查是否与其他分类冲突
        if args['name'] is not None or args['type'] is not None:
            name = args['name'] if args['name'] is not None else category.name
            type_val = args['type'] if args['type'] is not None else category.type
            existing_category = BillCategory.query.filter(
                BillCategory.name == name,
                BillCategory.type == type_val,
                BillCategory.id != category_id
            ).first()
            if existing_category:
                return api_response({'message': '同名分类已存在'}, code=400)
        
        # 更新字段
        if args['name'] is not None:
            category.name = args['name']
        if args['icon'] is not None:
            category.icon = args['icon']
        if args['type'] is not None:
            category.type = args['type']
        if args['sort_order'] is not None:
            category.sort_order = args['sort_order']
        
        db.session.commit()
        
        return api_response(category.to_dict(), message='分类更新成功')
    
    def delete(self, category_id):
        """删除账单分类"""
        category = BillCategory.query.get(category_id)
        if not category:
            return api_response({'message': '分类不存在'}, code=404)
        
        # 检查是否有子分类或记录关联
        sub_categories_count = BillSubCategory.query.filter_by(category_id=category_id).count()
        records_count = Record.query.filter_by(category_id=category_id).count()
        
        if sub_categories_count > 0 or records_count > 0:
            return api_response({'message': '该分类下有关联的子分类或记录，无法删除'}, code=400)
        
        db.session.delete(category)
        db.session.commit()
        
        return api_response(None, message='分类删除成功')

class BillSubCategoryList(Resource):
    def get(self):
        """获取账单子分类列表"""
        parser = reqparse.RequestParser()
        parser.add_argument('category_id', type=int, location='args')
        args = parser.parse_args()
        
        query = BillSubCategory.query
        if args['category_id'] is not None:
            query = query.filter_by(category_id=args['category_id'])
        
        sub_categories = query.order_by(BillSubCategory.sort_order, BillSubCategory.id).all()
        
        return api_response({
            'sub_categories': [sub_category.to_dict() for sub_category in sub_categories]
        })
    
    def post(self):
        """创建账单子分类"""
        parser = reqparse.RequestParser()
        parser.add_argument('category_id', type=int, required=True, help='父分类ID不能为空')
        parser.add_argument('name', type=str, required=True, help='子分类名称不能为空')
        parser.add_argument('icon', type=str)
        parser.add_argument('sort_order', type=int, default=0)
        args = parser.parse_args()
        
        # 检查父分类是否存在
        parent_category = BillCategory.query.get(args['category_id'])
        if not parent_category:
            return api_response({'message': '父分类不存在'}, code=404)
        
        # 检查同名子分类是否已存在
        existing_sub_category = BillSubCategory.query.filter_by(
            category_id=args['category_id'], 
            name=args['name']
        ).first()
        if existing_sub_category:
            return api_response({'message': '同名子分类已存在'}, code=400)
        
        sub_category = BillSubCategory(
            category_id=args['category_id'],
            name=args['name'],
            icon=args['icon'],
            sort_order=args['sort_order']
        )
        
        db.session.add(sub_category)
        db.session.commit()
        
        return api_response(sub_category.to_dict(), message='子分类创建成功')

class BillSubCategoryDetail(Resource):
    def get(self, sub_category_id):
        """获取账单子分类详情"""
        sub_category = BillSubCategory.query.get(sub_category_id)
        if not sub_category:
            return api_response({'message': '子分类不存在'}, code=404)
        
        return api_response(sub_category.to_dict())
    
    def put(self, sub_category_id):
        """更新账单子分类"""
        sub_category = BillSubCategory.query.get(sub_category_id)
        if not sub_category:
            return api_response({'message': '子分类不存在'}, code=404)
        
        parser = reqparse.RequestParser()
        parser.add_argument('category_id', type=int)
        parser.add_argument('name', type=str)
        parser.add_argument('icon', type=str)
        parser.add_argument('sort_order', type=int)
        args = parser.parse_args()
        
        # 检查父分类是否存在
        if args['category_id'] is not None:
            parent_category = BillCategory.query.get(args['category_id'])
            if not parent_category:
                return api_response({'message': '父分类不存在'}, code=404)
            sub_category.category_id = args['category_id']
        
        # 如果名称和父分类有修改，检查是否与其他子分类冲突
        if args['name'] is not None or args['category_id'] is not None:
            name = args['name'] if args['name'] is not None else sub_category.name
            category_id = args['category_id'] if args['category_id'] is not None else sub_category.category_id
            existing_sub_category = BillSubCategory.query.filter(
                BillSubCategory.category_id == category_id,
                BillSubCategory.name == name,
                BillSubCategory.id != sub_category_id
            ).first()
            if existing_sub_category:
                return api_response({'message': '同名子分类已存在'}, code=400)
        
        # 更新字段
        if args['name'] is not None:
            sub_category.name = args['name']
        if args['icon'] is not None:
            sub_category.icon = args['icon']
        if args['sort_order'] is not None:
            sub_category.sort_order = args['sort_order']
        
        db.session.commit()
        
        return api_response(sub_category.to_dict(), message='子分类更新成功')
    
    def delete(self, sub_category_id):
        """删除账单子分类"""
        sub_category = BillSubCategory.query.get(sub_category_id)
        if not sub_category:
            return api_response({'message': '子分类不存在'}, code=404)
        
        # 检查是否有记录关联
        records_count = Record.query.filter_by(sub_category_id=sub_category_id).count()
        
        if records_count > 0:
            return api_response({'message': '该子分类下有关联的记录，无法删除'}, code=400)
        
        db.session.delete(sub_category)
        db.session.commit()
        
        return api_response(None, message='子分类删除成功')

class RecordList(Resource):
    def get(self):
        """获取账单记录列表"""
        parser = reqparse.RequestParser()
        parser.add_argument('user_id', type=int, location='args')
        parser.add_argument('type', type=int, location='args')  # 0-支出, 1-收入
        parser.add_argument('category_id', type=int, location='args')
        parser.add_argument('sub_category_id', type=int, location='args')
        parser.add_argument('start_date', type=str, location='args')
        parser.add_argument('end_date', type=str, location='args')
        parser.add_argument('page', type=int, default=1, location='args')
        parser.add_argument('size', type=int, default=10, location='args')
        args = parser.parse_args()
        
        query = Record.query
        
        # 添加查询条件
        if args['user_id'] is not None:
            query = query.filter_by(user_id=args['user_id'])
        if args['type'] is not None:
            query = query.filter_by(type=args['type'])
        if args['category_id'] is not None:
            query = query.filter_by(category_id=args['category_id'])
        if args['sub_category_id'] is not None:
            query = query.filter_by(sub_category_id=args['sub_category_id'])
        if args['start_date'] is not None:
            try:
                start_date = datetime.strptime(args['start_date'], '%Y-%m-%d').date()
                query = query.filter(Record.record_date >= start_date)
            except ValueError:
                return api_response({'message': '开始日期格式错误'}, code=400)
        if args['end_date'] is not None:
            try:
                end_date = datetime.strptime(args['end_date'], '%Y-%m-%d').date()
                query = query.filter(Record.record_date <= end_date)
            except ValueError:
                return api_response({'message': '结束日期格式错误'}, code=400)
        
        # 分页查询
        records = query.order_by(Record.record_date.desc(), Record.created_at.desc()).paginate(
            page=args['page'], 
            per_page=args['size'], 
            error_out=False
        )
        
        return api_response({
            'total': records.total,
            'page': args['page'],
            'size': args['size'],
            'records': [record.to_dict() for record in records.items]
        })
    
    def post(self):
        """创建账单记录"""
        parser = reqparse.RequestParser()
        parser.add_argument('user_id', type=int, required=True, help='用户ID不能为空')
        parser.add_argument('amount', type=float, required=True, help='金额不能为空')
        parser.add_argument('type', type=int, required=True, help='类型不能为空')
        parser.add_argument('category_id', type=int, required=True, help='分类ID不能为空')
        parser.add_argument('sub_category_id', type=int)
        parser.add_argument('description', type=str)
        parser.add_argument('record_date', type=str, required=True, help='记录日期不能为空')
        args = parser.parse_args()
        
        # 检查用户是否存在
        user = User.query.get(args['user_id'])
        if not user:
            return api_response({'message': '用户不存在'}, code=404)
        
        # 检查分类是否存在
        category = BillCategory.query.get(args['category_id'])
        if not category:
            return api_response({'message': '分类不存在'}, code=404)
        
        # 检查子分类是否存在
        sub_category = None
        if args['sub_category_id'] is not None:
            sub_category = BillSubCategory.query.get(args['sub_category_id'])
            if not sub_category:
                return api_response({'message': '子分类不存在'}, code=404)
            # 检查子分类是否属于指定的分类
            if sub_category.category_id != args['category_id']:
                return api_response({'message': '子分类与分类不匹配'}, code=400)
        
        # 解析日期
        try:
            record_date = datetime.strptime(args['record_date'], '%Y-%m-%d').date()
        except ValueError:
            return api_response({'message': '记录日期格式错误'}, code=400)
        
        record = Record(
            user_id=args['user_id'],
            amount=args['amount'],
            type=args['type'],
            category_id=args['category_id'],
            sub_category_id=args['sub_category_id'],
            description=args['description'],
            record_date=record_date
        )
        
        db.session.add(record)
        db.session.commit()
        
        return api_response(record.to_dict(), message='记录创建成功')

class RecordDetail(Resource):
    def get(self, record_id):
        """获取账单记录详情"""
        record = Record.query.get(record_id)
        if not record:
            return api_response({'message': '记录不存在'}, code=404)
        
        return api_response(record.to_dict())
    
    def put(self, record_id):
        """更新账单记录"""
        record = Record.query.get(record_id)
        if not record:
            return api_response({'message': '记录不存在'}, code=404)
        
        parser = reqparse.RequestParser()
        parser.add_argument('user_id', type=int)
        parser.add_argument('amount', type=float)
        parser.add_argument('type', type=int)
        parser.add_argument('category_id', type=int)
        parser.add_argument('sub_category_id', type=int)
        parser.add_argument('description', type=str)
        parser.add_argument('record_date', type=str)
        args = parser.parse_args()
        
        # 检查用户是否存在
        if args['user_id'] is not None:
            user = User.query.get(args['user_id'])
            if not user:
                return api_response({'message': '用户不存在'}, code=404)
            record.user_id = args['user_id']
        
        # 更新字段
        if args['amount'] is not None:
            record.amount = args['amount']
        if args['type'] is not None:
            record.type = args['type']
        if args['category_id'] is not None:
            # 检查分类是否存在
            category = BillCategory.query.get(args['category_id'])
            if not category:
                return api_response({'message': '分类不存在'}, code=404)
            record.category_id = args['category_id']
        if args['sub_category_id'] is not None:
            if args['sub_category_id'] == 0:  # 0表示清空子分类
                record.sub_category_id = None
            else:
                # 检查子分类是否存在
                sub_category = BillSubCategory.query.get(args['sub_category_id'])
                if not sub_category:
                    return api_response({'message': '子分类不存在'}, code=404)
                # 检查子分类是否属于指定的分类
                if args['category_id'] is not None:
                    category_id = args['category_id']
                else:
                    category_id = record.category_id
                if sub_category.category_id != category_id:
                    return api_response({'message': '子分类与分类不匹配'}, code=400)
                record.sub_category_id = args['sub_category_id']
        if args['description'] is not None:
            record.description = args['description']
        if args['record_date'] is not None:
            try:
                record_date = datetime.strptime(args['record_date'], '%Y-%m-%d').date()
                record.record_date = record_date
            except ValueError:
                return api_response({'message': '记录日期格式错误'}, code=400)
        
        db.session.commit()
        
        return api_response(record.to_dict(), message='记录更新成功')
    
    def delete(self, record_id):
        """删除账单记录"""
        record = Record.query.get(record_id)
        if not record:
            return api_response({'message': '记录不存在'}, code=404)
        
        db.session.delete(record)
        db.session.commit()
        
        return api_response(None, message='记录删除成功')